package importselector;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AspectJTypeFilter;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;
import java.util.*;

/**
 * @author wuli
 * @create 2021-12-27 22:34
 */
public class CustomImportSelector implements ImportSelector {

    private String expression;

    private String customPackage;

    public CustomImportSelector() {
        try {
            Properties properties = PropertiesLoaderUtils.loadAllProperties("customimportselector.properties");
            expression = properties.getProperty("custom.import.selector.expression");
            customPackage = properties.getProperty("custom.import.selector.package");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        String[] basePackages = null;
        List<String> list = null;
        if (importingClassMetadata.hasAnnotation(ComponentScan.class.getName())) {
            Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());
            list = new ArrayList<String>(Arrays.asList((String[]) annotationAttributes.get("basePackages")));
        }

        if (list == null || list.size() == 0) {
            String basePackage = null;
            try {
                basePackage = Class.forName(importingClassMetadata.getClassName()).getPackage().getName();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            list = new ArrayList<String>();
            list.add(basePackage);
        }

        if (customPackage != null) {
            list.add(customPackage);
        }

        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        TypeFilter typeFilter = new AspectJTypeFilter(expression, CustomImportSelector.class.getClassLoader());
        scanner.addIncludeFilter(typeFilter);
        Set<String> classes = new HashSet<String>();
        for (String basePackage : list) {
            scanner.findCandidateComponents(basePackage).forEach(bean -> classes.add(bean.getBeanClassName()));
        }

        return classes.toArray(new String[classes.size()]);
    }
}
